home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / misc / gs261src.zip / zht2.c < prev    next >
C/C++ Source or Header  |  1993-05-13  |  10KB  |  324 lines

  1. /* Copyright (C) 1992 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* zht2.c */
  20. /* Level 2 halftone operators for Ghostscript */
  21. #include "ghost.h"
  22. #include "errors.h"
  23. #include "oper.h"
  24. #include "dict.h"
  25. #include "dparam.h"
  26. #include "iname.h"        /* for name_eq */
  27. #include "state.h"
  28. #include "store.h"
  29.  
  30. /* Structures (should be shared with gsht.c) */
  31. typedef struct screen_params_s {
  32.     float frequency;
  33.     float angle;
  34.     float (*spot_function)(P2(floatp, floatp));
  35. } screen_params;
  36. typedef struct threshold_params_s {
  37.     int width;
  38.     int height;
  39.     const byte *thresholds;
  40. } threshold_params;
  41.  
  42. /* Structures for component names in halftone dictionaries */
  43. typedef struct screen_names_s {
  44.     ref Frequency;
  45.     ref Angle;
  46.     ref SpotFunction;
  47. } screen_names;
  48. typedef struct threshold_names_s {
  49.     ref Width;
  50.     ref Height;
  51.     ref Thresholds;
  52. } threshold_names;
  53.  
  54. /* Forward references */
  55. private int dict_screen_params(P4(const ref *, const screen_names *,
  56.   screen_params *, ref *));
  57. private int dict_threshold_params(P3(const ref *, const threshold_names *,
  58.   threshold_params *));
  59.  
  60. /* Keys in halftone dictionaries: */
  61. static ref name_HalftoneType;
  62. static ref name_TransferFunction;
  63. /* Type 1: */
  64. static screen_names names_type1;
  65. static ref name_AccurateScreens;
  66. static ref name_ActualFrequency;
  67. static ref name_ActualAngle;
  68. /* Type 2: */
  69. static screen_names names_type2[4];
  70. /* Type 3: */
  71. static threshold_names names_type3;
  72. /* Type 4: */
  73. static threshold_names names_type4[4];
  74. /* Type 5: */
  75. static ref color_names[8];
  76. /* Red, Green, Blue, Gray must be 0-3. */
  77. #define name_Red color_names[0]
  78. #define name_Green color_names[1]
  79. #define name_Blue color_names[2]
  80. #define name_Gray color_names[3]
  81. #define name_Cyan color_names[4]
  82. #define name_Magenta color_names[5]
  83. #define name_Yellow color_names[6]
  84. #define name_Black color_names[7]
  85. static ref name_Default;
  86.  
  87. /* Initialization */
  88. private void
  89. zht2_init(void)
  90. {    static const names_def htn[] = {
  91.  
  92.     /* Create the names of the halftone dictionary keys. */
  93.        { "HalftoneType", &name_HalftoneType },
  94.        { "TransferFunction", &name_TransferFunction },
  95.         /* Type 1: */
  96.        { "Frequency", &names_type1.Frequency },
  97.        { "Angle", &names_type1.Angle },
  98.        { "SpotFunction", &names_type1.SpotFunction },
  99.        { "AccurateScreens", &name_AccurateScreens },
  100.        { "ActualFrequency", &name_ActualFrequency },
  101.        { "ActualAngle", &name_ActualAngle },
  102.         /* Type 2: */
  103.        { "RedFrequency", &names_type2[0].Frequency },
  104.        { "RedAngle", &names_type2[0].Angle },
  105.        { "RedSpotFunction", &names_type2[0].SpotFunction },
  106.        { "GreenFrequency", &names_type2[1].Frequency },
  107.        { "GreenAngle", &names_type2[1].Angle },
  108.        { "GreenSpotFunction", &names_type2[1].SpotFunction },
  109.        { "BlueFrequency", &names_type2[2].Frequency },
  110.        { "BlueAngle", &names_type2[2].Angle },
  111.        { "BlueSpotFunction", &names_type2[2].SpotFunction },
  112.        { "GrayFrequency", &names_type2[3].Frequency },
  113.        { "GrayAngle", &names_type2[3].Angle },
  114.        { "GraySpotFunction", &names_type2[3].SpotFunction },
  115.         /* Type 3: */
  116.        { "Width", &names_type3.Width },
  117.        { "Height", &names_type3.Height },
  118.        { "Thresholds", &names_type3.Thresholds },
  119.         /* Type 4: */
  120.        { "RedWidth", &names_type4[0].Width },
  121.        { "RedHeight", &names_type4[0].Height },
  122.        { "RedThresholds", &names_type4[0].Thresholds },
  123.        { "GreenWidth", &names_type4[1].Width },
  124.        { "GreenHeight", &names_type4[1].Height },
  125.        { "GreenThresholds", &names_type4[1].Thresholds },
  126.        { "BlueWidth", &names_type4[2].Width },
  127.        { "BlueHeight", &names_type4[2].Height },
  128.        { "BlueThresholds", &names_type4[2].Thresholds },
  129.        { "GrayWidth", &names_type4[3].Width },
  130.        { "GrayHeight", &names_type4[3].Height },
  131.        { "GrayThresholds", &names_type4[3].Thresholds },
  132.         /* Type 5 only: */
  133.        { "Red", &name_Red },
  134.        { "Green", &name_Green },
  135.        { "Blue", &name_Blue },
  136.        { "Gray", &name_Gray },
  137.        { "Cyan", &name_Cyan },
  138.        { "Magenta", &name_Magenta },
  139.        { "Yellow", &name_Yellow },
  140.        { "Black", &name_Black },
  141.        { "Default", &name_Default },
  142.  
  143.     /* Mark the end of the initialized name list. */
  144.        names_def_end
  145.     };
  146.  
  147.     init_names(htn);
  148. }
  149.  
  150.  
  151. /* - .currenthalftone <dict> 0 */
  152. /* - .currenthalftone <frequency> <angle> <proc> 1 */
  153. /* - .currenthalftone <red_freq> ... <gray_proc> 2 */
  154. private int
  155. zcurrenthalftone(register os_ptr op)
  156. {    if ( !r_has_type(&istate.halftone, t_null) )
  157.     {    /* Screen was set by sethalftone. */
  158.         push(2);
  159.         op[-1] = istate.halftone;
  160.         make_int(op, 0);
  161.     }
  162.     else if ( 1 )
  163.     {    /* Screen was set by setscreen. */
  164.         float freq, angle;
  165.         float (*proc)(P2(floatp, floatp));
  166.         gs_currentscreen(igs, &freq, &angle, &proc);
  167.         push(4);
  168.         make_real(op - 3, freq);
  169.         make_real(op - 2, angle);
  170.         op[-1] = istate.screen_procs.gray;
  171.         make_int(op, 1);
  172.     }
  173.     else
  174.     {    /* Screen was set by setcolorscreen. */
  175.         push(13);
  176.         make_real(op, 2);
  177.     }
  178.     return 0;
  179. }
  180.  
  181. /* <dict> .sethalftone1 - */
  182. private int
  183. zsethalftone1(register os_ptr op)
  184. {    screen_params par;
  185.     ref spot;
  186.     int code;
  187.     check_dict_read(*op);
  188.     code = dict_screen_params(op, &names_type1, &par, &spot);
  189.     if ( code < 0 ) return code;
  190.     /* NYI */
  191.     pop(1);
  192.     return 0;
  193. }
  194.  
  195. /* <dict> .sethalftone2 - */
  196. private int
  197. zsethalftone2(register os_ptr op)
  198. {    screen_params par[4];
  199.     ref spot[4];
  200.     int i;
  201.     check_dict_read(*op);
  202.     for ( i = 0; i < 4; i++ )
  203.     {    int code = dict_screen_params(op, &names_type2[i],
  204.                           &par[i], &spot[i]);
  205.         if ( code < 0 ) return code;
  206.     }
  207.     /* NYI */
  208.     pop(1);
  209.     return 0;
  210. }
  211.  
  212. /* <dict> .sethalftone3 - */
  213. private int
  214. zsethalftone3(register os_ptr op)
  215. {    threshold_params par;
  216.     int code;
  217.     check_dict_read(*op);
  218.     code = dict_threshold_params(op, &names_type3, &par);
  219.     if ( code < 0 ) return code;
  220.     /* NYI */
  221.     pop(1);
  222.     return 0;
  223. }
  224.  
  225. /* <dict> .sethalftone4 - */
  226. private int
  227. zsethalftone4(register os_ptr op)
  228. {    threshold_params par[4];
  229.     int i;
  230.     check_dict_read(*op);
  231.     for ( i = 0; i < 4; i++ )
  232.     {    int code = dict_threshold_params(op, &names_type4[i],
  233.                          &par[i]);
  234.         if ( code < 0 ) return code;
  235.     }
  236.     /* NYI */
  237.     pop(1);
  238.     return 0;
  239. }
  240.  
  241. /* <dict> .sethalftone5 - */
  242. private int
  243. zsethalftone5(register os_ptr op)
  244. {    uint length;
  245.     typedef union { struct { screen_params p; ref r; } s; threshold_params t; } ht_params;
  246.     ht_params *phts;
  247.     int index;
  248.     ht_params *p;
  249.     ref elt[2];            /* key, value */
  250.     check_dict_read(*op);
  251.     length = dict_length(op);
  252.     phts = (ht_params *)alloc(length, sizeof(ht_params), ".sethalftone5");
  253.     if ( phts == 0 )
  254.         return_error(e_VMerror);
  255.     index = dict_first(op);
  256.     p = phts;
  257.     /* BOGUS: doesn't save the name, .... */
  258.     while ( (index = dict_next(op, index, &elt[0])) >= 0 )
  259.     {    int code;
  260.         check_dict_read(elt[1]);
  261.         if ( (code = dict_screen_params(&elt[0], &names_type1,
  262.                 &p->s.p, &p->s.r)) == e_undefined )
  263.         {    code = dict_threshold_params(&elt[0], &names_type3,
  264.                              &p->t);
  265.         }
  266.         if ( code < 0 ) return code;
  267.     }
  268.     /* NYI */
  269.     pop(1);
  270.     return 0;
  271. }
  272.  
  273. /* ------ Initialization procedure ------ */
  274.  
  275. op_def zht2_op_defs[] = {
  276.     {"0.currenthalftone", zcurrenthalftone},
  277.     {"1.sethalftone1", zsethalftone1},
  278.     {"1.sethalftone2", zsethalftone2},
  279.     {"1.sethalftone3", zsethalftone3},
  280.     {"1.sethalftone4", zsethalftone4},
  281.     {"1.sethalftone5", zsethalftone5},
  282.     op_def_end(zht2_init)
  283. };
  284.  
  285. /* ------ Internal routines ------ */
  286.  
  287. /* Extract frequency, angle, and spot function from a dictionary. */
  288. private int
  289. dict_screen_params(const ref *pdict, const screen_names *pnames,
  290.   screen_params *psp, ref *pproc)
  291. {    int code;
  292.     ref *sproc;
  293.     if ( (code = dict_float_param(pdict, &pnames->Frequency, 0.0,
  294.                       &psp->frequency)) < 0 ||
  295.          (code = dict_float_param(pdict, &pnames->Angle, 0.0,
  296.                            &psp->angle)) < 0 ||
  297.          (code = dict_find(pdict, &pnames->SpotFunction, &sproc)) < 0
  298.        )
  299.         return code;
  300.     check_proc(*sproc);
  301.     *pproc = *sproc;
  302.     return 0;
  303. }
  304.  
  305. /* Extract width, height, and thresholds from a dictionary. */
  306. private int
  307. dict_threshold_params(const ref *pdict, const threshold_names *pnames,
  308.   threshold_params *ptp)
  309. {    int code;
  310.     ref *tstring;
  311.     if ( (code = dict_int_param(pdict, &pnames->Width, 1, 0x7fff, -1,
  312.                     &ptp->width)) < 0 ||
  313.          (code = dict_int_param(pdict, &pnames->Height, 1, 0x7fff, -1,
  314.                     &ptp->height)) < 0 ||
  315.          (code = dict_find(pdict, &pnames->Thresholds, &tstring)) < 0
  316.        )
  317.         return code;
  318.     check_read_type(*tstring, t_string);
  319.     if ( r_size(tstring) != (long)ptp->width * ptp->height )
  320.         return_error(e_rangecheck);
  321.     ptp->thresholds = tstring->value.const_bytes;
  322.     return 0;
  323. }
  324.